#include "quote_server.h"
#include "logger.h"
#include <iostream>
#include <string>
#include <sstream>
#include <thread>
#include <chrono>
#include <csignal>

using namespace yquote;

// 全局服务器实例
std::unique_ptr<QuoteServer> g_server;

// 初始化日志系统
void initializeLogger() {
    auto& logger = Logger::getInstance();
    
    // 设置日志级别
    logger.setLevel(LogLevel::INFO);
    
    // 添加控制台输出（带颜色）
    auto console_sink = std::make_shared<ConsoleSink>(true);
    logger.addSink(console_sink);
    
    // 添加文件输出
    try {
        auto file_sink = std::make_shared<FileSink>("logs/yquote.log", true);
        logger.addSink(file_sink);
    } catch (const std::exception& e) {
        std::cout << "警告: 无法创建日志文件: " << e.what() << std::endl;
    }
    
    // 添加滚动文件输出（每个文件最大10MB，保留5个文件）
    try {
        auto rotating_sink = std::make_shared<RotatingFileSink>("logs/yquote_rotating.log", 10 * 1024 * 1024, 5);
        logger.addSink(rotating_sink);
    } catch (const std::exception& e) {
        std::cout << "警告: 无法创建滚动日志文件: " << e.what() << std::endl;
    }
    
    // 可选：启用异步模式以提高性能
    // logger.setAsync(true);
    
    LOG_INFO("日志系统初始化完成");
}

// 信号处理函数
void signalHandler(int signal) {
    LOG_INFO_FMT("收到信号 %d，正在关闭服务器...", signal);
    if (g_server) {
        g_server->stop();
    }
    exit(0);
}

// 打印帮助信息
void printHelp() {
    std::cout << "\n=== 行情服务器控制台 ===" << std::endl;
    std::cout << "可用命令:" << std::endl;
    std::cout << "  help    - 显示帮助信息" << std::endl;
    std::cout << "  status  - 显示服务器状态" << std::endl;
    std::cout << "  stats   - 显示统计信息" << std::endl;
    std::cout << "  config  - 显示当前配置" << std::endl;
    std::cout << "  clients - 显示连接的客户端" << std::endl;
    std::cout << "  quotes  - 显示所有行情数据" << std::endl;
    std::cout << "  add <symbol> <price> - 添加新股票" << std::endl;
    std::cout << "  remove <symbol> - 移除股票" << std::endl;
    std::cout << "  interval <ms> - 设置更新间隔(毫秒)" << std::endl;
    std::cout << "  volatility <percent> - 设置价格波动率" << std::endl;
    std::cout << "  loglevel <level> - 设置日志级别(TRACE/DEBUG/INFO/WARN/ERROR/FATAL)" << std::endl;
    std::cout << "  stop    - 停止服务器" << std::endl;
    std::cout << "  quit    - 退出程序" << std::endl;
    std::cout << "========================\n" << std::endl;
}

// 处理用户命令
void processCommand(const std::string& command) {
    if (command == "help") {
        printHelp();
    } else if (command == "status") {
        std::cout << "服务器状态: " << (g_server->isRunning() ? "运行中" : "已停止") << std::endl;
        LOG_DEBUG_FMT("用户查询服务器状态: %s", g_server->isRunning() ? "运行中" : "已停止");
    } else if (command == "stats") {
        g_server->printStatistics();
        LOG_DEBUG("用户查询统计信息");
    } else if (command == "config") {
        g_server->getConfigManager().printConfig();
        LOG_DEBUG("用户查询配置信息");
    } else if (command == "clients") {
        auto client_ids = g_server->getWebSocketServer().getClientIds();
        std::cout << "连接的客户端 (" << client_ids.size() << "):" << std::endl;
        for (const auto& id : client_ids) {
            std::cout << "  " << id << std::endl;
        }
        LOG_DEBUG_FMT("用户查询客户端列表，当前连接数: %zu", client_ids.size());
    } else if (command == "quotes") {
        auto quotes = g_server->getQuoteManager().getAllQuotes();
        std::cout << "当前行情数据 (" << quotes.size() << "):" << std::endl;
        for (const auto& quote : quotes) {
            std::cout << "  " << quote.symbol << ": " << quote.price 
                      << " (涨跌: " << quote.change_percent << "%)" << std::endl;
        }
        LOG_DEBUG_FMT("用户查询行情数据，当前股票数: %zu", quotes.size());
    } else if (command.substr(0, 4) == "add ") {
        // 解析添加股票命令
        std::istringstream iss(command.substr(4));
        std::string symbol;
        double price;
        if (iss >> symbol >> price) {
            g_server->getMarketDataSimulator().addSymbol(symbol, price);
            std::cout << "已添加股票: " << symbol << " (价格: " << price << ")" << std::endl;
            LOG_INFO_FMT("用户添加股票: %s, 价格: %.2f", symbol.c_str(), price);
        } else {
            std::cout << "命令格式错误，请使用: add <symbol> <price>" << std::endl;
            LOG_WARN("用户输入了错误的add命令格式");
        }
    } else if (command.substr(0, 7) == "remove ") {
        std::string symbol = command.substr(7);
        g_server->getMarketDataSimulator().removeSymbol(symbol);
        std::cout << "已移除股票: " << symbol << std::endl;
        LOG_INFO_FMT("用户移除股票: %s", symbol.c_str());
    } else if (command.substr(0, 9) == "interval ") {
        int interval = std::stoi(command.substr(9));
        g_server->getMarketDataSimulator().setUpdateInterval(interval);
        std::cout << "更新间隔已设置为: " << interval << "ms" << std::endl;
        LOG_INFO_FMT("用户设置更新间隔: %d ms", interval);
    } else if (command.substr(0, 11) == "volatility ") {
        double volatility = std::stod(command.substr(11));
        g_server->getMarketDataSimulator().setPriceVolatility(volatility);
        std::cout << "价格波动率已设置为: " << volatility << "%" << std::endl;
        LOG_INFO_FMT("用户设置价格波动率: %.2f%%", volatility);
    } else if (command.substr(0, 9) == "loglevel ") {
        std::string level_str = command.substr(9);
        LogLevel level;
        if (level_str == "TRACE") level = LogLevel::TRACE;
        else if (level_str == "DEBUG") level = LogLevel::DEBUG;
        else if (level_str == "INFO") level = LogLevel::INFO;
        else if (level_str == "WARN") level = LogLevel::WARN;
        else if (level_str == "ERROR") level = LogLevel::ERROR;
        else if (level_str == "FATAL") level = LogLevel::FATAL;
        else {
            std::cout << "无效的日志级别: " << level_str << std::endl;
            std::cout << "可用级别: TRACE, DEBUG, INFO, WARN, ERROR, FATAL" << std::endl;
            return;
        }
        Logger::getInstance().setLevel(level);
        std::cout << "日志级别已设置为: " << level_str << std::endl;
        LOG_INFO_FMT("用户设置日志级别: %s", level_str.c_str());
    } else if (command == "stop") {
        g_server->stop();
        std::cout << "服务器已停止" << std::endl;
        LOG_INFO("用户停止服务器");
    } else if (command == "quit" || command == "exit") {
        g_server->stop();
        std::cout << "再见！" << std::endl;
        LOG_INFO("用户退出程序");
        exit(0);
    } else if (!command.empty()) {
        std::cout << "未知命令: " << command << "，输入 'help' 查看帮助" << std::endl;
        LOG_WARN_FMT("用户输入未知命令: %s", command.c_str());
    }
}

void printUsage(const char* program_name) {
    std::cout << "用法: " << program_name << " [选项]" << std::endl;
    std::cout << "选项:" << std::endl;
    std::cout << "  -p, --port <端口号>     指定WebSocket端口 (默认: 8080)" << std::endl;
    std::cout << "  -c, --config <文件>     指定配置文件路径 (默认: config/server.conf)" << std::endl;
    std::cout << "  -l, --loglevel <级别>   指定日志级别 (TRACE/DEBUG/INFO/WARN/ERROR/FATAL, 默认: INFO)" << std::endl;
    std::cout << "  -h, --help              显示此帮助信息" << std::endl;
    std::cout << std::endl;
    std::cout << "示例:" << std::endl;
    std::cout << "  " << program_name << "                    # 使用默认配置" << std::endl;
    std::cout << "  " << program_name << " -p 9090            # 指定端口" << std::endl;
    std::cout << "  " << program_name << " -c my_config.conf  # 指定配置文件" << std::endl;
    std::cout << "  " << program_name << " -l DEBUG           # 设置调试级别日志" << std::endl;
}

int main(int argc, char* argv[]) {
    std::cout << "=== YQuote 实时行情订阅服务 ===" << std::endl;
    std::cout << "版本: 0.0.1" << std::endl;
    std::cout << "作者: DevilIsY" << std::endl;
    std::cout << "==============================\n" << std::endl;
    
    // 初始化日志系统
    initializeLogger();
    
    // 设置信号处理
    signal(SIGINT, signalHandler);
    signal(SIGTERM, signalHandler);
    
    // 解析命令行参数
    int port = 8080;
    std::string config_file = "config/server.conf";
    LogLevel log_level = LogLevel::INFO;
    
    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        
        if (arg == "-h" || arg == "--help") {
            printUsage(argv[0]);
            return 0;
        } else if (arg == "-p" || arg == "--port") {
            if (i + 1 < argc) {
                port = std::atoi(argv[++i]);
                if (port <= 0 || port > 65535) {
                    LOG_ERROR_FMT("无效的端口号: %s", argv[i]);
                    std::cerr << "无效的端口号: " << argv[i] << std::endl;
                    return 1;
                }
            } else {
                std::cerr << "选项 " << arg << " 需要一个参数" << std::endl;
                return 1;
            }
        } else if (arg == "-c" || arg == "--config") {
            if (i + 1 < argc) {
                config_file = argv[++i];
            } else {
                std::cerr << "选项 " << arg << " 需要一个参数" << std::endl;
                return 1;
            }
        } else if (arg == "-l" || arg == "--loglevel") {
            if (i + 1 < argc) {
                std::string level_str = argv[++i];
                if (level_str == "TRACE") log_level = LogLevel::TRACE;
                else if (level_str == "DEBUG") log_level = LogLevel::DEBUG;
                else if (level_str == "INFO") log_level = LogLevel::INFO;
                else if (level_str == "WARN") log_level = LogLevel::WARN;
                else if (level_str == "ERROR") log_level = LogLevel::ERROR;
                else if (level_str == "FATAL") log_level = LogLevel::FATAL;
                else {
                    LOG_ERROR_FMT("无效的日志级别: %s", level_str.c_str());
                    std::cerr << "无效的日志级别: " << level_str << std::endl;
                    return 1;
                }
            } else {
                std::cerr << "选项 " << arg << " 需要一个参数" << std::endl;
                return 1;
            }
        } else if (arg[0] == '-') {
            std::cerr << "未知选项: " << arg << std::endl;
            printUsage(argv[0]);
            return 1;
        } else {
            // 兼容旧版本：第一个非选项参数作为端口号
            port = std::atoi(arg.c_str());
            if (port <= 0 || port > 65535) {
                LOG_ERROR_FMT("无效的端口号: %s", arg.c_str());
                std::cerr << "无效的端口号: " << arg << std::endl;
                return 1;
            }
        }
    }
    
    // 设置日志级别
    Logger::getInstance().setLevel(log_level);
    
    try {
        // 创建并启动服务器
        LOG_INFO_FMT("正在创建服务器，端口: %d, 配置文件: %s", port, config_file.c_str());
        g_server = std::make_unique<QuoteServer>(port, config_file);
        
        if (!g_server->start()) {
            LOG_ERROR("启动服务器失败");
            return 1;
        }
        
        // 等待一下让服务器完全启动
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        
        std::cout << "服务器已启动，WebSocket端口: " << port << std::endl;
        std::cout << "配置文件: " << config_file << std::endl;
        std::cout << "输入 'help' 查看可用命令，输入 'quit' 退出\n" << std::endl;
        
        LOG_INFO_FMT("服务器启动成功，WebSocket端口: %d", port);
        
        // 主循环 - 处理用户输入
        std::string input;
        while (g_server->isRunning()) {
            std::cout << "yquote> ";
            std::getline(std::cin, input);
            
            // 去除首尾空格
            input.erase(0, input.find_first_not_of(" \t"));
            input.erase(input.find_last_not_of(" \t") + 1);
            
            processCommand(input);
        }
        
    } catch (const std::exception& e) {
        LOG_FATAL_FMT("服务器异常: %s", e.what());
        std::cerr << "服务器异常: " << e.what() << std::endl;
        return 1;
    }
    
    LOG_INFO("程序正常退出");
    return 0;
} 